/* SDLSurface.cpp
 *
 * --
 * Copyright (c) 2012, Christophe Huriaux
 * Distributed under the terms of the MIT license.
 * http://www.opensource.org/licenses/mit-license.php
 * --
 */

#include <cstring>
#include <debug/logger.h>
#include <SDL/SDL_image.h>
#include <graphics/SDLSurface.h>

#if SDL_BYTEORDER == SDL_LIL_ENDIAN
# define SDLSURFACE_RMASK 0x000000FF
# define SDLSURFACE_GMASK 0x0000FF00
# define SDLSURFACE_BMASK 0x00FF0000
# define SDLSURFACE_AMASK 0xFF000000
#else
# define SDLSURFACE_RMASK 0xFF000000
# define SDLSURFACE_GMASK 0x00FF0000
# define SDLSURFACE_BMASK 0x0000FF00
# define SDLSURFACE_AMASK 0x000000FF
#endif

SDLSurface::SDLSurface()
	: surface(NULL)
{

}

SDLSurface::SDLSurface(SDL_Surface* s)
	: surface(s)
{

}

SDLSurface::SDLSurface(SDLSurface& s)
	: surface(s.surface)
{
	s.surface->refcount++;
}

SDLSurface::~SDLSurface()
{
	if (surface != NULL)
		SDL_FreeSurface(surface);
}


unsigned int
SDLSurface::getWidth()
{
	if (surface == NULL)
		return 0;
	return surface->w;
}

unsigned int
SDLSurface::getHeight()
{
	if (surface == NULL)
		return 0;
	return surface->h;
}

const void*
SDLSurface::rawData()
{
	if (surface == NULL)
		return NULL;
	return surface->pixels;
}

bool
SDLSurface::isInitialized()
{
	return (surface != NULL)?true:false;
}


SDLSurface&
SDLSurface::convertToRGBA8()
{
	if (surface == NULL)
		return *this;

	SDL_PixelFormat f = *(surface->format);
	f.BitsPerPixel = 32;
	f.BytesPerPixel = 4;
	f.Rmask = SDLSURFACE_RMASK;
	f.Gmask = SDLSURFACE_GMASK;
	f.Bmask = SDLSURFACE_BMASK;
	f.Amask = SDLSURFACE_AMASK;

	SDL_Surface* rgba8Surface = SDL_ConvertSurface(surface, &f,
		SDL_SWSURFACE);

	SDL_FreeSurface(surface);
	surface = rgba8Surface;

	return *this;
}

SDLSurface&
SDLSurface::flip()
{
	if (surface == NULL)
		return *this;

	SDL_Surface* fSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
		surface->w, surface->h, surface->format->BitsPerPixel,
		surface->format->Rmask, surface->format->Gmask, surface->format->Bmask,
		surface->format->Amask);

	SDL_LockSurface(surface);
	SDL_LockSurface(fSurface);

	int p = surface->pitch;
	for (int i = 0; i < surface->h; i++)
		memcpy(&((unsigned char*)fSurface->pixels)[i*p],
			&((unsigned char*)surface->pixels)[(surface->h - i - 1)*p], p);

	SDL_UnlockSurface(surface);
	SDL_UnlockSurface(fSurface);
	SDL_FreeSurface(surface);
	surface = fSurface;

	return *this;
}

SDL_Surface*
SDLSurface::loadFromFile(const char* filename)
{
	return IMG_Load(filename);
}
